package com.example.detectivedemo.infrastructure.player;

import com.example.detectivedemo.domain.player.Player;
import com.example.detectivedemo.domain.player.PlayerRepository;
import com.huawei.hmf.tasks.Task;
import com.huawei.hmf.tasks.Tasks;
import com.huawei.hms.support.hwid.result.AuthHuaweiId;
import ohos.agp.utils.DataAbilityUtils;
import ohos.data.DatabaseHelper;
import ohos.data.rdb.RdbOpenCallback;
import ohos.data.rdb.RdbStore;
import ohos.data.rdb.ValuesBucket;
import ohos.data.resultset.ResultSet;
import ohos.data.valueholder.ValueHolder;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.media.image.PixelMap;
import ohos.media.image.common.Size;
import ohos.security.keystore.KeyStoreException;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * 本地玩家仓库实现
 * 使用鸿蒙系统的RDB数据库存储玩家数据
 */
public class LocalPlayerRepository implements PlayerRepository {
    
    private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "LocalPlayerRepository");
    private static final String DB_NAME = "detective_game.db";
    private static final int DB_VERSION = 1;
    
    private static final String TABLE_PLAYER = "player";
    private static final String COLUMN_PLAYER_ID = "player_id";
    private static final String COLUMN_USERNAME = "username";
    private static final String COLUMN_NICKNAME = "nickname";
    private static final String COLUMN_AVATAR = "avatar";
    private static final String COLUMN_LEVEL = "level";
    private static final String COLUMN_EXPERIENCE = "experience";
    private static final String COLUMN_SOLVED_CASES = "solved_cases";
    private static final String COLUMN_TOTAL_SCORE = "total_score";
    private static final String COLUMN_IS_LOGIN = "is_login";
    
    private RdbStore rdbStore;
    private DatabaseHelper databaseHelper;
    
    // 简单的内存缓存，用于提高性能
    private Map<String, Player> playerCache = new HashMap<>();
    
    public LocalPlayerRepository(DatabaseHelper helper) {
        this.databaseHelper = helper;
        initDatabase();
    }
    
    // 初始化数据库
    private void initDatabase() {
        RdbOpenCallback callback = new RdbOpenCallback() {
            @Override
            public void onCreate(RdbStore store) {
                // 创建玩家表
                String createTableSql = "CREATE TABLE IF NOT EXISTS " + TABLE_PLAYER + " (" +
                        COLUMN_PLAYER_ID + " TEXT PRIMARY KEY, " +
                        COLUMN_USERNAME + " TEXT UNIQUE NOT NULL, " +
                        COLUMN_NICKNAME + " TEXT NOT NULL, " +
                        COLUMN_AVATAR + " TEXT, " +
                        COLUMN_LEVEL + " INTEGER DEFAULT 1, " +
                        COLUMN_EXPERIENCE + " INTEGER DEFAULT 0, " +
                        COLUMN_SOLVED_CASES + " INTEGER DEFAULT 0, " +
                        COLUMN_TOTAL_SCORE + " INTEGER DEFAULT 0, " +
                        COLUMN_IS_LOGIN + " BOOLEAN DEFAULT FALSE" +
                        ")";
                store.executeSql(createTableSql);
            }
            
            @Override
            public void onUpgrade(RdbStore store, int oldVersion, int newVersion) {
                // 数据库升级逻辑
                HiLog.i(LABEL, "onUpgrade: oldVersion=%{public}d, newVersion=%{public}d", oldVersion, newVersion);
            }
        };
        
        // 获取RDB存储实例
        rdbStore = databaseHelper.getRdbStore(DB_NAME, DB_VERSION, callback, null);
    }
    
    @Override
    public Player create(Player player) {
        // 构建ValuesBucket
        ValuesBucket values = new ValuesBucket();
        values.putString(COLUMN_PLAYER_ID, player.getPlayerId());
        values.putString(COLUMN_USERNAME, player.getUsername());
        values.putString(COLUMN_NICKNAME, player.getNickname());
        values.putString(COLUMN_AVATAR, player.getAvatar());
        values.putInteger(COLUMN_LEVEL, player.getLevel());
        values.putInteger(COLUMN_EXPERIENCE, player.getExperience());
        values.putInteger(COLUMN_SOLVED_CASES, player.getSolvedCases());
        values.putInteger(COLUMN_TOTAL_SCORE, player.getTotalScore());
        values.putBoolean(COLUMN_IS_LOGIN, player.isLogin());
        
        // 插入数据
        long rowId = rdbStore.insert(TABLE_PLAYER, values);
        
        if (rowId > 0) {
            // 缓存玩家信息
            playerCache.put(player.getPlayerId(), player);
            return player;
        } else {
            throw new RuntimeException("创建玩家失败");
        }
    }
    
    @Override
    public Optional<Player> findById(String playerId) {
        // 先从缓存查找
        if (playerCache.containsKey(playerId)) {
            return Optional.of(playerCache.get(playerId));
        }
        
        // 从数据库查找
        String sql = "SELECT * FROM " + TABLE_PLAYER + " WHERE " + COLUMN_PLAYER_ID + " = ?";
        ResultSet resultSet = rdbStore.querySql(sql, new String[]{playerId});
        
        Player player = null;
        if (resultSet != null && resultSet.goToFirstRow()) {
            player = resultSetToPlayer(resultSet);
            // 缓存玩家信息
            playerCache.put(playerId, player);
        }
        
        if (resultSet != null) {
            resultSet.close();
        }
        
        return Optional.ofNullable(player);
    }
    
    @Override
    public Optional<Player> findByUsername(String username) {
        // 先从缓存查找
        for (Player player : playerCache.values()) {
            if (player.getUsername().equals(username)) {
                return Optional.of(player);
            }
        }
        
        // 从数据库查找
        String sql = "SELECT * FROM " + TABLE_PLAYER + " WHERE " + COLUMN_USERNAME + " = ?";
        ResultSet resultSet = rdbStore.querySql(sql, new String[]{username});
        
        Player player = null;
        if (resultSet != null && resultSet.goToFirstRow()) {
            player = resultSetToPlayer(resultSet);
            // 缓存玩家信息
            playerCache.put(player.getPlayerId(), player);
        }
        
        if (resultSet != null) {
            resultSet.close();
        }
        
        return Optional.ofNullable(player);
    }
    
    @Override
    public Player update(Player player) {
        // 构建ValuesBucket
        ValuesBucket values = new ValuesBucket();
        values.putString(COLUMN_NICKNAME, player.getNickname());
        values.putString(COLUMN_AVATAR, player.getAvatar());
        values.putInteger(COLUMN_LEVEL, player.getLevel());
        values.putInteger(COLUMN_EXPERIENCE, player.getExperience());
        values.putInteger(COLUMN_SOLVED_CASES, player.getSolvedCases());
        values.putInteger(COLUMN_TOTAL_SCORE, player.getTotalScore());
        values.putBoolean(COLUMN_IS_LOGIN, player.isLogin());
        
        // 更新数据
        String whereClause = COLUMN_PLAYER_ID + " = ?";
        int rowsUpdated = rdbStore.update(TABLE_PLAYER, values, whereClause, new String[]{player.getPlayerId()});
        
        if (rowsUpdated > 0) {
            // 更新缓存
            playerCache.put(player.getPlayerId(), player);
            return player;
        } else {
            throw new RuntimeException("更新玩家失败");
        }
    }
    
    @Override
    public boolean delete(String playerId) {
        String whereClause = COLUMN_PLAYER_ID + " = ?";
        int rowsDeleted = rdbStore.delete(TABLE_PLAYER, whereClause, new String[]{playerId});
        
        if (rowsDeleted > 0) {
            // 从缓存删除
            playerCache.remove(playerId);
            return true;
        }
        return false;
    }
    
    @Override
    public boolean savePlayerState(Player player) {
        // 这里简化处理，直接调用update方法
        try {
            update(player);
            return true;
        } catch (Exception e) {
            HiLog.e(LABEL, "savePlayerState failed: %{public}s", e.getMessage());
            return false;
        }
    }
    
    @Override
    public Optional<Player> loadPlayerState(String playerId) {
        // 这里简化处理，直接调用findById方法
        return findById(playerId);
    }
    
    // 将ResultSet转换为Player对象
    private Player resultSetToPlayer(ResultSet resultSet) {
        Player player = new Player();
        player.setPlayerId(resultSet.getString(resultSet.getColumnIndexForName(COLUMN_PLAYER_ID)));
        player.setUsername(resultSet.getString(resultSet.getColumnIndexForName(COLUMN_USERNAME)));
        player.setNickname(resultSet.getString(resultSet.getColumnIndexForName(COLUMN_NICKNAME)));
        player.setAvatar(resultSet.getString(resultSet.getColumnIndexForName(COLUMN_AVATAR)));
        player.setLevel(resultSet.getInt(resultSet.getColumnIndexForName(COLUMN_LEVEL)));
        player.setExperience(resultSet.getInt(resultSet.getColumnIndexForName(COLUMN_EXPERIENCE)));
        player.setSolvedCases(resultSet.getInt(resultSet.getColumnIndexForName(COLUMN_SOLVED_CASES)));
        player.setTotalScore(resultSet.getInt(resultSet.getColumnIndexForName(COLUMN_TOTAL_SCORE)));
        player.setLogin(resultSet.getBoolean(resultSet.getColumnIndexForName(COLUMN_IS_LOGIN)));
        return player;
    }
}